package one.stand.service.impl;

import cn.hutool.core.util.StrUtil;
import com.jmp.autocofiguration.util.OssUtil2;
import com.jmp.base.dto.MessagePushClientEnum;
import com.jmp.base.dto.MessagePushRequest;
import com.jmp.base.dto.MessagePushType;
import com.jmp.feign.MessageFeign;
import com.jmp.feign.SmsFeign;
import lombok.Builder;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import one.stand.advice.ResultEnum;
import one.stand.mapper.TicketAccountMapperExt;
import one.stand.mapper.TicketOrderMapperExt;
import one.stand.mapper.TicketTimeMapperExt;
import one.stand.model.Company;
import one.stand.model.TicketAccount;
import one.stand.model.TicketOrder;
import one.stand.model.TicketTime;
import one.stand.service.CompanyBaseService;
import one.stand.service.TicketService;
import one.stand.service.sys.SysDictValueService;
import one.stand.service.user.UserAdminService;
import one.stand.util.AssertUtil;
import one.stand.util.RequestContext;
import one.stand.util.RequestContextHolder;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Objects;

/**
 * @author cjr
 */
@Service
@Slf4j
public class TicketServiceImpl implements TicketService {

    @Autowired
    private MessageFeign messageFeign;
    @Autowired
    private SmsFeign smsFeign;

    @Autowired
    private CompanyBaseService companyBaseService;
    @Autowired
    private SysDictValueService sysDictValueService;
    @Autowired
    private UserAdminService userAdminService;

    @Autowired
    private TicketOrderMapperExt ticketOrderMapperExt;
    @Autowired
    private TicketAccountMapperExt ticketAccountMapperExt;
    @Autowired
    private TicketTimeMapperExt ticketTimeMapperExt;

    public TicketTime getTicketTime() {
        return ticketTimeMapperExt.selectOn();
    }

    @Override
    @Transactional
    public void orderSave(Integer id, Integer fromCompanyId, BigDecimal orderMoney, String orderNo, String photo, String payPhoto) {

        TicketTime ticketTime = getTicketTime();
        AssertUtil.isTrue((new Date()).before(ticketTime.getOrderEndTime()), ResultEnum.PARAM_CHECK, "订单截止日期已到");

        AssertUtil.nonNull(fromCompanyId, ResultEnum.PARAM_CHECK, "未选择进货企业");
        Company company = companyBaseService.getById(fromCompanyId);
        AssertUtil.nonNull(company, ResultEnum.PARAM_CHECK, "没有该进货企业");
        AssertUtil.nonNull(orderMoney, ResultEnum.PARAM_CHECK, "请输入进货金额");
        AssertUtil.nonNull(orderNo, ResultEnum.PARAM_CHECK, "请正确填写销售单编号");
        AssertUtil.isTrue(NumberUtils.isDigits(orderNo) && orderNo.length() == 7, ResultEnum.PARAM_CHECK, "请正确填写七位数销售单编号");
        AssertUtil.nonNull(photo, ResultEnum.PARAM_CHECK, "请上传销售单");
        AssertUtil.nonNull(payPhoto, ResultEnum.PARAM_CHECK, "请上传付款截图");

        int count = ticketOrderMapperExt.selectNo(ticketTime.getId(), orderNo);
        AssertUtil.isTrue(count <= 0, ResultEnum.PARAM_CHECK, "销售单编号重复");

        photo = OssUtil2.getWebsiteUrlReplace(photo);
        payPhoto = OssUtil2.getWebsiteUrlReplace(payPhoto);

        photo = StrUtil.removeSuffix(photo, ",");
        payPhoto = StrUtil.removeSuffix(payPhoto, ",");

        RequestContext.User optUser = RequestContextHolder.getRequestContext().getUser();

        if (Objects.nonNull(id)) {
            TicketOrder order = ticketOrderMapperExt.selectByPrimaryKey(id);
            AssertUtil.isTrue(order.getCreater().equals(optUser.getUserId()), ResultEnum.FAIL);
            AssertUtil.isTrue(order.getType().equals(ticketTime.getId()), ResultEnum.FAIL);
            int i = ticketOrderMapperExt.updateInfo(id, fromCompanyId, orderMoney, orderNo, orderNo, photo, payPhoto);
            AssertUtil.isTrue(i == 1, ResultEnum.FAIL);
        } else {

            TicketOrder order = new TicketOrder();
            order.setType(ticketTime.getId());
            order.setCompanyId(Objects.nonNull(optUser.getCompanyId()) ? optUser.getCompanyId() : DEFALUT_COMPANY);
            order.setFromCompanyId(fromCompanyId);
            order.setOrderMoeny(orderMoney);
            order.setOrderNo(orderNo);
            order.setPhoto(photo);
            order.setPayPhoto(payPhoto);
            order.setStatus(STATUS_ING);
            order.setCreater(optUser.getUserId());
            ticketOrderMapperExt.insertSelective(order);
        }

        // sms
//        DictDto sysDictValue = sysDictValueService.get2(SysDictValueService.Type.CONFIG, SysDictValueService.TypeName.SMS_JXS_TICKET_SAVE);
//        if (Objects.nonNull(sysDictValue)) {
//            String companyName;
//            if (Objects.nonNull(optUser.getCompanyId())) {
//                Company companyCreator = companyBaseService.getById(optUser.getCompanyId());
//                companyName = companyCreator.getCompanyName();
//            } else {
//                UserDto optUserModel = userAdminService.get(optUser.getUserId());
//                companyName = optUserModel.getName() + "(个人)";
//            }

//            SmsParam smsParam = SmsParam.builder().company(companyName).build();
//            smsFeign.sendBatchSms(SmsSendRequest.builder()
//                    .type(SmsCodeEnums.jxsTicketSave.getCode())
//                    .phones(Lists.newArrayList(sysDictValue.getValue()))
//                    .params(JSON.toJSONString(smsParam))
//                    .build());
//        } else {
//            log.warn("config:SMS_JXS_TICKET_SAVE is null");
//        }
    }

    @Override
    @Transactional
    public void orderPass(Integer id) {

        TicketOrder order = ticketOrderMapperExt.selectByPrimaryKey(id);
        AssertUtil.isTrue(order.getStatus() != STATUS_PASS, ResultEnum.PARAM_CHECK, "已审核通过");

        int count = ticketOrderMapperExt.selectNo(order.getType(), order.getOrderNo());
        AssertUtil.isTrue(count <= 0, ResultEnum.PARAM_CHECK, "销售单编号重复");

        RequestContext.User user = RequestContextHolder.getRequestContext().getUser();
        int i = ticketOrderMapperExt.updateAgree(id, null, STATUS_PASS, user.getUserId(), order.getType(), order.getStatus());
        AssertUtil.isTrue(i == 1, "操作失败");

        updateAccount(order.getType(), order.getCreater(), order.getOrderMoeny());

        ticketOrderMapperExt.updateRefuseByNo(user.getUserId(), order.getType(), order.getOrderNo(), STATUS_ING, STATUS_REFUSE, "销售单编号被重复使用");

        // push
        String[] arr = {order.getOrderNo()};
        MessagePushRequest pushRequest = MessagePushRequest.builder()
                .clientEnum(MessagePushClientEnum.CRM_JXS)
                .type(MessagePushType.TICKET_ORDER_PASS)
                .toId(order.getCreater())
                .fillData(arr)
                .build();
        messageFeign.push(pushRequest);
    }

    @Override
    @Transactional
    public void orderRefuse(Integer id, String memo) {

        TicketOrder order = ticketOrderMapperExt.selectByPrimaryKey(id);
        AssertUtil.isTrue(order.getStatus() != STATUS_REFUSE, ResultEnum.PARAM_CHECK, "已拒绝");

        RequestContext.User user = RequestContextHolder.getRequestContext().getUser();
        int i = ticketOrderMapperExt.update(id, memo, STATUS_REFUSE, user.getUserId(), order.getType(), order.getStatus());
        AssertUtil.isTrue(i == 1, "操作失败");

        if (order.getStatus() == STATUS_PASS) {
            updateAccount(order.getType(), order.getCreater(), order.getOrderMoeny().negate());
        }

        // push
        String[] arr = {order.getOrderNo()};
        MessagePushRequest pushRequest = MessagePushRequest.builder()
                .clientEnum(MessagePushClientEnum.CRM_JXS)
                .type(MessagePushType.TICKET_ORDER_REFUSE)
                .toId(order.getCreater())
                .title(memo)
                .fillData(arr)
                .build();
        messageFeign.push(pushRequest);
    }

    @Override
    public void orderMemo(Integer id, String memoTel) {
        TicketOrder ticketOrder = new TicketOrder();
        ticketOrder.setId(id);
        ticketOrder.setMemoTel(memoTel);
        ticketOrderMapperExt.updateByPrimaryKeySelective(ticketOrder);

        if (StringUtils.isNoneBlank(memoTel)) {
            TicketOrder ticketOrderSelect = ticketOrderMapperExt.selectByPrimaryKey(id);
            ticketOrderMapperExt.updateMemoAuto(ticketOrderSelect.getCreater());
        }
    }

    @Override
    @Transactional
    public void use(Integer id, Integer checkUser) {
        int i = ticketAccountMapperExt.updateUse(id, checkUser);
        AssertUtil.isTrue(i == 1, "操作失败");
    }

    private void updateAccount(Integer type, Integer userId, BigDecimal money) {
        TicketAccount ticketAccount = ticketAccountMapperExt.select(type, userId);
        if (Objects.isNull(ticketAccount)) {
            TicketAccount account = new TicketAccount();
            account.setType(type);
            account.setUserId(userId);
            ticketAccountMapperExt.insertSelective(account);

            updateAccount(account.getId(), money);
        } else {
            updateAccount(ticketAccount.getId(), money);
        }
    }

    private void updateAccount(Integer id, BigDecimal money) {
        if (Objects.nonNull(money) && money.compareTo(BigDecimal.ZERO) != 0) {
            int orderNum = money.compareTo(BigDecimal.ZERO) > 0 ? 1 : -1;
            int i = ticketAccountMapperExt.update(id, money, orderNum);
            AssertUtil.isTrue(i == 1, "操作失败");
            ticketAccountMapperExt.updateNum(id, getTicketTime().getMoney());
        }
    }

    @Data
    @Builder
    private static class SmsParam {
        private String company;
    }
}
